﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DoNetToolKit.Patterns.SimpletFactory;
using DoNetToolKit.Patterns.Singleton;
using DoNetToolKit.Algorithm;
using DoNetToolKit.Patterns.Strategy;

namespace DoNetToolKit
{
    class Program
    {
        static void Main(string[] args)
        {
            PatternsTest();
            //AlgorithmTest();
            Console.ReadLine();
        }

        #region 设计模式
        static void PatternsTest()
        {
            //SimpletFactoryTest();
            //SingletonTest();
            StartegyTest();
        }

        #region 工厂模式
        /***
         * 
         * 工厂模式：
         * 主要是为创建对象提供过渡接口，
         * 以便将创建对象的具体过程（new关键字和具体的构造器）隐藏起来，
         * 用一个工厂方法来代替，对外提供的只是一个工厂方法，达到提高灵活性的目的。
         * 
         * 优点：
         *     1.隐蔽了new关键字和构造器
         *     2.降低了这个对象与别的类之间的耦合度，提高了程序的可扩展性
         *       原因：当子类被别的类替换，或者构造器的参数发生变化的时候，
         *       只需改动工厂方法内的new即可，改动量降到了最低，
         *       而如果不用工厂模式，而是直接用new关键字的话，需要改动的地方就很多了
         *     3.把对象的设计和实现分割开来，从而代码扩展性强、灵活性更高。
         *     
         * 思想：用一个方法来代替new关键字和构造器。
        ***/

        // 简单工厂模式
        /***
         * 
         * 简单工厂模式:
         * 简单工厂模式是使用一个工厂对象决定创建出某个产品类的实例。
         * 
         * 由一个工厂对象根据传入的参数值确定创建出哪一个产品类的实例。
         * 简单工厂模式涉及三个角色:
         *     抽象产品对象（Product）角色：
         *         担任这个角色的类是工厂方法所创建对象的父类或者共同拥有的接口。 
         *     具体产品角色（concreator）:
         *         工厂方法所创建的对象都是这个角色的实例。 
         *     工厂角色（creator）：
         *         担任这个角色的是工厂方法模式的核心，含有与应用紧密相连的商业逻辑。 
         * 
         * 优点：实现了责任的分割。即客户端只负责“消费”产品，产品的生产就是由工厂去生产。
         * 缺点：工厂类成了个核心的核心，它实现了产品的所有逻辑。
         * 一旦工厂类失效，整个都要受到影响。所有的业务逻辑都在工厂类，耦合度高，不容易扩展。
         * 由于工厂方法是静态的，所以工厂角色无法形成基于继承的等级结构。 
         * 
        ***/
        static void SimpletFactoryTest()
        {
            // 静态工厂模式/简单工厂模式
            Fruit fruit = SimpletFactory.GetFruitInstance(FruitType.Apple);
            //Fruit fruit = SimpletFactory.GetFruitInstance(FruitType.Orange);
            //Fruit fruit = SimpletFactory.GetFruitInstance(FruitType.Banana);
            if (fruit != null)
            {
                fruit.PrintFruitType();
            }
        }
        #endregion

        // 单例模式：一个类只有一个实例
        static void SingletonTest()
        {
            Singleton singleton = Singleton.GetInstance();
        }

        // 策略模式：定义了一系列的算法，并将每一个算法封装起来，而且使它们还可以相互替换。
        static void StartegyTest()
        {
            StrategyMain.StrategyTest();            
        }
        #endregion
        #region 算法
        static void AlgorithmTest()
        {
            // 二分查找法
            BinarySearch binarySearch = new BinarySearch();
            binarySearch.Search();
        }
        #endregion
    }
}